/**
 * @file    drv_flash.h
 * @author  yhy
 * @brief   flash抽象层
 * @version 1.01
 * @date    2025-08-13
 *
 * @copyright Copyright (c) 2025
 *
 * @details
 * Change Logs:
 * Date           Author       Notes
 * 2025-08-13     yhy          the first version V1.00
 * 2025-08-26     yhy          add get sram size function V1.01
 *
 */
#ifndef __DRV_FLASH_H__
#define __DRV_FLASH_H__

#include "common_config.h"

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>

#define FLASH_PFLASH_SIZE 0x80000U                                              /* P-Flash大小 512K */
#define FLASH_DFLASH_SIZE 0x20000U                                              /* D-Flash大小 128K */

#define FLASH_PFLASH_BASE_ADDR 0x10000000U                                      /* P-Flash起始地址 */
#define FLASH_DFLASH_BASE_ADDR 0x18000000U                                      /* D-Flash起始地址 */

#define FLASH_PFLASH_END_ADDR (FLASH_PFLASH_BASE_ADDR + FLASH_PFLASH_SIZE - 1U) /* P-Flash结束地址 */
#define FLASH_DFLASH_END_ADDR (FLASH_DFLASH_BASE_ADDR + FLASH_DFLASH_SIZE - 1U) /* D-Flash结束地址 */

#define FLASH_PAGE_SIZE (2048U)                                                 /* IM94x Flash页大小: 2KB */

/* Flash设备名称定义 */
#define FLASH_DEV_NAME_PFLASH "pflash"
#define FLASH_DEV_NAME_DFLASH "dflash"

/* 分区名称定义 */
#define FLASH_PART_NAME_APP1 "app1"
#define FLASH_PART_NAME_APP2 "app2"
#define FLASH_PART_NAME_DATA "data"

/* 分区表魔术字 */
#define FLASH_PART_MAGIC_WORD 0x4550 /* "EP" */

/**
 * @brief Flash区域类型
 *
 */
typedef enum
{
    FLASH_AREA_TYPE_PFLASH = 0U, /*!< P-Flash area */
    FLASH_AREA_TYPE_DFLASH = 1U, /*!< D-Flash area */
    FLASH_AREA_TYPE_MAX,
} snf_flash_area_type_e;

/**
 * @brief Flash设备信息结构体
 */
typedef struct
{
    char     name[16];       /*!< Flash设备名称 */
    uint32_t base_addr;      /*!< Flash基地址(起始地址) */
    size_t   len;            /*!< Flash大小 */
    size_t   erase_blk_size; /*!< Flash擦除块大小 */

    struct
    {
        result_e (*init)(void);
        result_e (*read)(long offset, uint8_t *buf, size_t size);
        result_e (*write)(long offset, const uint8_t *buf, size_t size);
        result_e (*erase)(long offset, size_t size);
    } ops_t; /*!< Flash操作函数指针结构体 */
} snf_flash_dev_t;

/**
 * @brief Flash分区信息结构体
 */
typedef struct
{
    uint32_t magic_word;     /*!< 分区表魔术字 */
    char     name[16];       /*!< 分区名称 */
    char     flash_name[16]; /*!< 所属Flash设备名称 */
    long     offset;         /*!< 分区在Flash中的偏移地址 */
    size_t   len;            /*!< 分区大小 */
    uint32_t reserved;       /*!< 保留字段 */
} snf_flash_partition_t;

/* Flash初始化 */
result_e snf_drv_flash_init(void);

/* Flash设备操作API */
const snf_flash_dev_t *snf_drv_flash_device_find(const char *name);
const snf_flash_dev_t *snf_drv_flash_device_get(size_t index);

/* 分区操作API */
const snf_flash_partition_t *snf_drv_flash_partition_find(const char *name);
const snf_flash_partition_t *snf_drv_flash_partition_get(size_t index);
result_e snf_drv_flash_partition_read(const snf_flash_partition_t *part, uint32_t addr, uint8_t *buf,
                                      size_t size);
result_e snf_drv_flash_partition_write(const snf_flash_partition_t *part, uint32_t addr, const uint8_t *buf,
                                       size_t size);
result_e snf_drv_flash_partition_erase(const snf_flash_partition_t *part, uint32_t addr, size_t size);
result_e snf_drv_flash_partition_erase_all(const snf_flash_partition_t *part);

/* 按设备类型操作 */
result_e snf_drv_flash_pflash_read(uint32_t offset, uint8_t *buf, size_t size);
result_e snf_drv_flash_pflash_write(uint32_t offset, const uint8_t *buf, size_t size);
result_e snf_drv_flash_pflash_erase(uint32_t offset, size_t size);

result_e snf_drv_flash_dflash_read(uint32_t offset, uint8_t *buf, size_t size);
result_e snf_drv_flash_dflash_write(uint32_t offset, const uint8_t *buf, size_t size);
result_e snf_drv_flash_dflash_erase(uint32_t offset, size_t size);

/* 获取内存大小信息 */
uint16_t snf_drv_flash_get_sram_size(void);

#endif
